package com.atguigu.gmall.mq.receiver;

import com.atguigu.gmall.mq.config.DeadLetterMqConfig;
import com.atguigu.gmall.mq.config.DelayedMqConfig;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 接收消息实现类
 */
@Component
@Slf4j
public class ReceiverMessage {


    //接收消息  延迟 基于延迟插件
    @RabbitListener(queues = DelayedMqConfig.queue_delay_1)
    public void delayMessage(String msg,Message message,Channel channel) throws Exception{
        log.info("接收延迟插件的消息：" + msg);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //接收消息 延迟 基于死信队列
    @RabbitListener(queues = DeadLetterMqConfig.queue_dead_2)
    public void deadLetterMessage(String msg,Message message,Channel channel) throws Exception{
        log.info("接收到死信消息：" + msg);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //接收消息  交换机应答  队列应答
    //队列 ： 要求持久化 不自动删除
    //MQ服务器中创建交换机  创建队列  创建绑定关系
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue.confirm",durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = "exchange.confirm",durable = "true",autoDelete = "false"),
            key = "routingKey.confirm"
    ))
    public void receiverConfirmMessage(String msg,Message message,Channel channel){
        try {
            System.out.println("接收消息：" + msg);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }




    //接收消息
//    @RabbitListener(queues = "sendTestQueue")
//    public void receiverMessage(String message){
//
//        System.out.println("第一个测试接收到的消息：" + message);
//          int i = 1/0;
//    }

    //接收消息 应答 表示确认  参数1：消息对象  参数2：消息的通道
    @RabbitListener(queues = "sendTestQueue")
    public void receiverMessage(Message message, Channel channel) throws IOException {
        try {
            System.out.println("接收到的消息：" + new String(message.getBody()));
            //应答之后抛出异常 消息不会再被接收到
            int i = 1/0;
            //手动应答  参数1： 通知队列消费可以删除 1  不能删除 2  参数2：接收到消息不用再发回队列
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //e.printStackTrace();//浪费性能
            //证明出现异常
            System.out.println("证明出现异常");
            //判断是否是第一次接收消息 并处理
            if(message.getMessageProperties().isRedelivered()){
                //第二次接收消息
                System.out.println("第二次接收消息出现异常");
                //不要再来第三次了  本次设置拒绝接收 消息
                //参数1：消息标记（消息的标识、证明是哪个消息）
                //参数2：不要将此消息放回队列    放回队列 true
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else{
                //第一次接收消息  让MQ再发第二次
                //参数1：消息标记（消息的标识、证明是哪个消息）
                //参数2：是否批量处理
                //参数2：不要将此消息放回队列
                System.out.println("第一次接收消息出现异常");
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),true ,true);
            }

        }

    }
}
